home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / incl / LEDA.020+881 / impl / olist.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-05  |  7.5 KB  |  319 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  olist.h
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #ifndef LEDA_OLIST_H
  16. #define LEDA_OLIST_H
  17.  
  18. #include <LEDA/basic.h>
  19.  
  20. //------------------------------------------------------------------------------
  21. //
  22. //  obj_list  (doubly linked lists of obj_links)
  23. //
  24. //  each "obj_link" may be present in at most one list 
  25. //  
  26. //------------------------------------------------------------------------------
  27.  
  28. class obj_list; 
  29. class obj_link;
  30.  
  31. typedef int  (*CMP_ITEM)(obj_link*,obj_link*);
  32. typedef void (*APP_ITEM)(obj_link*);
  33. typedef int  (*ORD_ITEM)(obj_link*);
  34.  
  35. //------------------------------------------------------------------------------
  36. // class obj_link (base class for all list items)
  37. //------------------------------------------------------------------------------
  38.  
  39. class obj_link {
  40.  
  41. protected:
  42.  
  43.   obj_link* succ_link;
  44.   obj_link* pred_link;
  45.  
  46. void del_item() 
  47. { pred_link->succ_link = succ_link; 
  48.   succ_link->pred_link = pred_link; 
  49.  }
  50.  
  51. public:
  52.  
  53. //  obj_link() { succ = nil; }
  54.  
  55.   obj_link* succ_item() { return succ_link; }
  56.   obj_link* pred_item() { return pred_link; }
  57.  
  58.   friend class obj_list;
  59.   friend class c_obj_list;
  60.   friend class graph;
  61.   friend class node_list;
  62.  
  63. };
  64.  
  65.  
  66. //------------------------------------------------------------------------------
  67. // obj_list: base class for all doubly linked lists
  68. //------------------------------------------------------------------------------
  69.  
  70. class obj_list {
  71.  
  72.    obj_link* h;           // head
  73.    obj_link* t;           // tail
  74.    int count;             // length of list
  75. //
  76. // obj_link* iterator;    // iterator
  77. //
  78.  
  79. void quick_sort(obj_link**,obj_link**,CMP_ITEM);
  80.  
  81. void insertion_sort(obj_link**,obj_link**,obj_link**,CMP_ITEM);
  82.  
  83. public:
  84.  
  85.  
  86. // access operations
  87.  
  88.    int  length() const { return count; }
  89.    int  size()   const { return count; }
  90.    bool empty()  const { return (count==0) ? true : false;}
  91.  
  92.    obj_link* first()               const { return h; }
  93.    obj_link* first_item()          const { return h; }
  94.    obj_link* last()                const { return t; }
  95.    obj_link* last_item()           const { return t; }
  96.    obj_link* next_item(obj_link* p)   const { return p->succ_link; }
  97.    obj_link* succ(obj_link* p)        const { return p->succ_link; }
  98.    obj_link* pred(obj_link* p)        const { return p->pred_link; }
  99.  
  100.    obj_link* cyclic_succ(obj_link* p) const 
  101.    { return p->succ_link? p->succ_link : h; }
  102.  
  103.    obj_link* cyclic_pred(obj_link* p) const 
  104.    { return p->pred_link? p->pred_link : t; }
  105.  
  106.    obj_link* succ(obj_link* l, int i) const; 
  107.    obj_link* pred(obj_link* l, int i) const;
  108.    obj_link* get_item(int = 0)     const; 
  109.  
  110.    obj_link* max(CMP_ITEM) const;
  111.    obj_link* min(CMP_ITEM) const;
  112.    obj_link* search(obj_link*) const;
  113.  
  114.    int    rank(obj_link*) const;
  115.  
  116. // update operations
  117.  
  118.    obj_link* insert(obj_link* p, obj_link* l);
  119.    obj_link* insert(obj_link* p, obj_link* l, int dir);
  120.    obj_link* push(obj_link* p);
  121.    obj_link* append(obj_link* p);
  122.  
  123.    void del(obj_link* loc);
  124.    obj_link* pop();
  125.    obj_link* Pop();
  126.  
  127.    void   conc(obj_list&);
  128.    void   split(obj_link*,obj_list&,obj_list&);
  129.    void   apply(APP_ITEM);
  130.    void   sort(CMP_ITEM);
  131.    void   bucket_sort(int,int,ORD_ITEM);
  132.    void   permute();
  133.    void   clear();
  134.  
  135.  
  136. /* // iteration
  137.  
  138.    obj_link* set_iterator(obj_link* p) const { return (obj_link*&)iterator=p;}
  139.    obj_link* start_iteration()       const { return set_iterator(h); }
  140.    obj_link* Start_iteration()       const { return set_iterator(t); }
  141.    obj_link* move_to_succ() const { return set_iterator(iterator->succ_link); }
  142.    obj_link* move_to_pred() const { return set_iterator(iterator->pred_link); }
  143.    obj_link* read_iterator(obj_link*& x)const { return x=iterator; }
  144.    obj_link* read_iterator()         const { return iterator; }
  145.  
  146.    void  reset()               const { set_iterator(nil); }
  147.    void  init_iterator()       const { set_iterator(nil); }
  148. */
  149.  
  150.  
  151.    obj_list& operator=(const obj_list&); 
  152.    obj_list  operator+(const obj_list&); 
  153.  
  154.  
  155. // constructors & destructors
  156.  
  157.    obj_list();    
  158.  
  159.    //obj_list(const obj_list&);
  160.  
  161.   ~obj_list()  { clear(); }
  162.  
  163. };
  164.  
  165.  
  166.  
  167. inline obj_link* obj_list::push(obj_link* p)   
  168. { count++;
  169.   p->pred_link = 0;
  170.   p->succ_link = h;
  171.   if (h) 
  172.       h = h->pred_link = p;
  173.   else   
  174.       h = t =  p;
  175.   return p;
  176.  }
  177.  
  178.  
  179. inline obj_link* obj_list::append(obj_link* p)
  180. { count++;
  181.   p->pred_link = t;
  182.   p->succ_link = 0;
  183.   if (t) 
  184.       t = t->succ_link = p;
  185.   else  
  186.       t = h = p;
  187.   return p; 
  188.  } 
  189.  
  190.  
  191. inline obj_link* obj_list::pop()    
  192. { obj_link* p=h; 
  193.   if (p) 
  194.   { if (--count) 
  195.       { h = h->succ_link; 
  196.         h->pred_link = 0; 
  197.        }
  198.     else  
  199.       h = t = 0;
  200.    }
  201.   return p;
  202.  }
  203.  
  204.  
  205. inline obj_link* obj_list::Pop()    
  206. { obj_link* p=t; 
  207.   if (p)
  208.   { if (--count) 
  209.       { t = t->pred_link; 
  210.         t->succ_link = 0; 
  211.        }
  212.     else  
  213.       h = t = 0;
  214.    }
  215.   return p;
  216.  }
  217.  
  218.  
  219. inline obj_link* obj_list::insert(obj_link* n, obj_link* p) 
  220. { // insert n insert after p
  221.   obj_link* s=p->succ_link;
  222.   n->pred_link = p;
  223.   n->succ_link = s;
  224.   p->succ_link = n;
  225.   if (p==t) t=n; else s->pred_link = n;
  226.   count++;
  227.   return n;
  228. }
  229.  
  230.  
  231.  
  232.  
  233. //------------------------------------------------------------------------------
  234. //
  235. // c_obj_list (doubly linked circular object list)
  236. //
  237. // simple and efficient implementation (no counter, iterator, sorting, etc.)
  238. // removed items are assigned a nil succ pointer 
  239. // member(x) <==>  x->succ != nil
  240. //
  241. //------------------------------------------------------------------------------
  242.  
  243. class c_obj_list : public obj_link {
  244.  
  245. // the list head is an obj_link, namely the predecessor of the first 
  246. // and the successor of the last element
  247.  
  248. public:
  249.  
  250. bool empty()  const { return (succ_link==(obj_link*)this) ? true : false;}
  251.  
  252. obj_link* first()      const { return (succ_link==(obj_link*)this) ? nil : succ_link; }
  253. obj_link* last()       const { return (pred_link==(obj_link*)this) ? nil : pred_link; }
  254. obj_link* first_item() const { return first(); }
  255. obj_link* last_item()  const { return last(); }
  256.  
  257. obj_link* next_item(obj_link* p) const { return succ(p); }
  258.  
  259. obj_link* succ(obj_link* p) const 
  260. { return (p->succ_link==(obj_link*)this)? nil : p->succ_link;}
  261.  
  262. obj_link* pred(obj_link* p) const 
  263. { return (p->pred_link==(obj_link*)this)? nil : p->pred_link;}
  264.  
  265. obj_link* cyclic_succ(obj_link* p) const 
  266. { return (p->succ_link==(obj_link*)this) ? pred_link : p->succ_link; }
  267.  
  268. obj_link* cyclic_pred(obj_link* p) const 
  269. { return (p->pred_link==(obj_link*)this) ? succ_link : p->pred_link; }
  270.  
  271.  
  272.  void insert(obj_link* n, obj_link* p) 
  273.  { // insert n insert after p
  274.    obj_link* s=p->succ_link;
  275.    n->pred_link = p;
  276.    n->succ_link = s;
  277.    p->succ_link = n;
  278.    s->pred_link = n;
  279.   }
  280.  
  281.  obj_link* del(obj_link* x)
  282.  { obj_link*  p = x->pred_link;
  283.    obj_link*  s = x->succ_link;
  284.    p->succ_link = s;
  285.    s->pred_link = p;
  286.    x->succ_link = nil;
  287.    return x;
  288.   }
  289.  
  290.  bool member(obj_link* x) { return x->succ_link != nil; }
  291.  
  292.  void push(obj_link* p)   { insert(p,this); }
  293.  void append(obj_link* p) { insert(p,pred_link); }
  294.  
  295.  obj_link* pop() { return del(succ_link); }
  296.  obj_link* Pop() { return del(pred_link); }
  297.  
  298.  void clear() 
  299.  { while(succ_link != this) 
  300.    { obj_link* p = succ_link;
  301.      succ_link = p->succ_link;
  302.      p->succ_link = nil;
  303.     }
  304.    pred_link = this; 
  305.   }
  306.  
  307.  void init() { succ_link = pred_link = this; }
  308.  
  309. // constructors & destructors
  310.  
  311.  c_obj_list()  { succ_link = pred_link = this; }
  312. ~c_obj_list()  { clear(); }
  313.  
  314. };
  315.  
  316.  
  317. #endif
  318.